/**************************************************************************************
*
*	Copyright (C) 2010 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	VertexBuffer.h
*
*	Description -	
*
*	Comments	-	Container for vertices. DX9 implementation for now.
*
*	Modification History:
*			Name			   Date					Description
*			CodeSushi	-	10/22/2010	-	Creation of this file
**************************************************************************************/

#ifndef _PSX_VERTEX_BUFFER_H_
#define _PSX_VERTEX_BUFFER_H_

#include "PulseSTD.h"
#include "GraphicsTypes.h"
#include "ResourcePoolItem.h"

#include <D3D9.h>

namespace Pulse
{
	struct VertexBufferDescription
	{
		// TODO: Add Vertex buffer declaration
		EVertexBufferType::Type bufferType;
		EPrimitiveType::Type	primitiveType;
		SIZE_T					vertexSize;
		SIZE_T					numVertices;
		SIZE_T					numPrimitives;
		void					*pData;
		// TODO: Add indexbuffer
		VertexDeclaration		*pDecl;
		BOOL					bDiscardData;

		VertexBufferDescription( void )
			: bufferType( EVertexBufferType::STATIC ), primitiveType( EPrimitiveType::TRIANGLE_LIST ), 
			vertexSize( sizeof( Vertex1P1D ) ), numVertices( 0 ), numPrimitives( 0 ), pData( NULL ),
			pDecl( NULL ), bDiscardData( TRUE )
		{
		}
	};

	class VertexBuffer : public IResourcePoolItem
	{
	public:

		VertexBuffer( void );
		VertexBuffer( VertexBufferDescription *pDesc );
		virtual ~VertexBuffer( void );

		// These defines the base interface for all derived resources
		virtual BOOL CreateResource( void );
		virtual BOOL DestroyResource( void );
		virtual BOOL DisableResource( void );
		virtual BOOL RestoreResource( void );

		// Default is NULL to use the resource name
		virtual BOOL LoadResource( const CHAR *pFilename = NULL );
		virtual BOOL SaveResource( const CHAR *pFilename = NULL );

		virtual EErrorCode::Type Initialize( void );

		virtual void Cleanup( void );

		virtual void Lock( POS_T start = 0, SIZE_T count = 0, void **pVertices = PSX_NULL );

		virtual void Unlock( void );

		virtual void Bind( void );

		virtual void Unbind( void ) { }

		virtual void Render( void );

		SIZE_T GetNumVertices( void ) const { return m_desc.numVertices; }

		void SetBufferDecription( const VertexBufferDescription *pDesc ) { m_desc = *pDesc; Initialize(); }

		VertexBufferDescription * GetBufferDescription( void ) { return &m_desc; }

		void SetVertexDeclaration( VertexDeclaration *pDecl ) { m_desc.pDecl = pDecl; }

		VertexDeclaration * GetVertexDeclaration( void ) const { return m_desc.pDecl; }

		const VertexBufferDescription * GetVertexBufferDescription( void ) const { return &m_desc; }

		void SetStreamIndex( UINT index ) { m_streamIndex = index; }

		UINT GetStreamIndex( void ) const { return m_streamIndex; }

	private:

		VertexBufferDescription m_desc;

		UINT m_streamIndex;
		UINT m_refCount;

		INT m_VBIndex;

		IDirect3DDevice9 *m_pDevice;
		IDirect3DVertexBuffer9 *m_pVB;

	};
}

#endif /* _PSX_VERTEX_BUFFER_H_ */